package de.slothsoft.wasbinich.android.database.webservice;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import de.slothsoft.android.authenticator.AuthenticationUtil;
import de.slothsoft.wasbinich.android.util.ActivityUtil;
import de.slothsoft.wasbinich.core.database.DatabaseException;
import de.slothsoft.wasbinich.core.database.DatabaseExceptionCode;
import de.slothsoft.wasbinich.core.database.webservice.AbstractOAuth2Authenticator;
import de.slothsoft.wasbinich.core.database.webservice.RestCommunicator;

public class AndroidOAuth2Authenticator extends AbstractOAuth2Authenticator {

    public static final String AUTHENTICATION_TYPE = "wasbinich"; //$NON-NLS-1$

    protected Account currentAccount;

    public AndroidOAuth2Authenticator(RestCommunicator restCommunicator) {
	super(restCommunicator);
    }

    @Override
    protected Token getAccessTokenFromUser() throws DatabaseException {
	final Account[] availableAccounts = getAvailableAccounts();
	if (availableAccounts.length == 0)
	    throw new DatabaseException(DatabaseExceptionCode.CANCELLED_BY_USER, "No account present."); //$NON-NLS-1$
	Account account = getCurrentAccount();
	String userId = account.name;
	String userPassword = getAccountManager().getPassword(account);
	return this.oAuth2Authenticator.getAccessToken(new User(userId, userPassword));
    }

    public void setCurrentAccount(Account currentAccount) {
	this.currentAccount = currentAccount;
    }

    public Account getCurrentAccount() {
	if (this.currentAccount != null)
	    return this.currentAccount;
	Account[] availableAccounts = getAvailableAccounts();
	this.currentAccount = availableAccounts.length == 0 ? null : availableAccounts[0];
	return this.currentAccount;
    }

    protected Account[] getAvailableAccounts() {
	final AccountManager manager = getAccountManager();
	Account[] result = manager.getAccountsByType(AuthenticationUtil.ACCOUNT_ID);
	if (result.length == 0) {
	    // force the user to create account
	    AuthenticationUtil.addNewAccount(ActivityUtil.getCurrentActivity(), AUTHENTICATION_TYPE);
	    result = manager.getAccountsByType(AuthenticationUtil.ACCOUNT_ID);
	}
	return result;
    }

    protected AccountManager getAccountManager() {
	Activity context = ActivityUtil.getCurrentActivity();
	return AccountManager.get(context);
    }

}
